home *** CD-ROM | disk | FTP | other *** search
- /*
- * REyes
- *
- * A screen blanker for the Retina graphics card.
- * By Michael Heinz, 8 January, 1994
- *
- * Main routines
- *
- */
-
- #include <exec/memory.h>
- #include <exec/ports.h>
- #include <exec/execbase.h>
- #include <graphics/displayinfo.h>
- #include <intuition/intuitionbase.h>
- #include <intuition/gadgetclass.h>
- #include <libraries/commodities.h>
- #include <libraries/gadtools.h>
- #include <dos/dosextens.h>
- #include <dos/dostags.h>
- #include <utility/tagitem.h>
-
- #include <clib/alib_protos.h>
- #include <clib/commodities_protos.h>
- #include <clib/dos_protos.h>
- #include <clib/exec_protos.h>
- #include <clib/gadtools_protos.h>
- #include <clib/graphics_protos.h>
- #include <clib/intuition_protos.h>
- #include <clib/macros.h>
- #include <clib/retina_protos.h>
- #include <retina/retina.h>
-
- #include <string.h>
- #include <stdlib.h>
-
- #include <pragmas/commodities_pragmas.h>
- #include <pragmas/dos_pragmas.h>
- #include <pragmas/exec_pragmas.h>
- #include <pragmas/gadtools_pragmas.h>
- #include <pragmas/graphics_pragmas.h>
- #include <pragmas/intuition_pragmas.h>
- #include <pragmas/retina_pragmas.h>
-
- #ifdef SMALLEYES
- #include "smalleyes.h"
- #else
- #include "retinaeyes.h"
- #endif
-
- UBYTE *VersionString = "$VER: REyes 1.2 (By Michael Heinz)";
-
- #define NORMAL_WIDE 640
- #define NORMAL_HIGH 480
- #define SMALL_WIDE 320
- #define SMALL_HIGH 240
-
- void
- chkabort(void)
- {
- }
-
- /*
- * Common Definitions
- */
-
- extern struct ExecBase *SysBase;
- extern struct DosLibrary *DOSBase;
- struct IntuitionBase *IntuitionBase;
- struct RetinaBase *RetinaBase;
- struct Library *CxBase, *GadToolsBase, *IconBase;
-
- #define FINDPROCPORT (&((struct Process *)SysBase->ThisTask)->pr_MsgPort)
-
-
- /*
- * A handy request structure for reporting that we've up and died.
- */
- struct EasyStruct quitreq =
- {
- sizeof(struct EasyStruct),
- 0,
- "REyes",
- "REyes has suffered an untimely demise\ndue to: %s",
- "OK|OK"
- };
-
- void
- Error(char *s)
- {
- if (s) EasyRequest(NULL,&quitreq,NULL,s);
- }
-
- /*
- * Definitions for our Commodity
- */
- struct NewBroker NewBroker =
- {NB_VERSION, "REyes ", "Retina Blanker V1.2",
- "Somebody's watching you...", NBU_NOTIFY | NBU_UNIQUE, COF_SHOW_HIDE,
- 0, NULL, 0};
-
- struct MsgPort *CxPort;
-
- UBYTE *PopKey;
- UBYTE *BlankKey;
-
- #define HOTKEY_OPEN_WINDOW 1L
- #define HOTKEY_BLANK_SCREEN 2L
-
- #define DEF_CX_PRI 0
- #define DEF_POPKEY "control alt s"
- #define DEF_BLANKKEY "lamiga s"
-
- LONG TimeOut, ClientTimeOut;
-
- #define MAX_TIMEOUT 3600L
- #define MAX_CLIENT_TIMEOUT 60L
-
- #define DEF_TIMEOUT 60L
- #define DEF_CLIENT_TIMEOUT 5L
-
- #define SERVER_PRI 3L
- #define CLIENT_PRI -5L
-
- /*
- * Definitions for Eye Movement
- */
- #define RAND(m) (Random(m)-(m)/2)
-
- #define MAX_SPEED 10L
- #define MAX_EYES 10L
- #define MAX_CHANCE 100L
-
- #define DEF_EYES 5L
- #define DEF_SPEED 4L
- #define DEF_CHANCE 10L
-
- #define DEF_MODE MID_DEFAULT_08
-
- LONG NumEyes, Speed, Chance;
-
- typedef struct {
- int NumEyes;
- Eyes *Eye[MAX_EYES];
- } EyeStruct;
-
-
- EyeStruct EyeList;
-
- /*
- * Definitions for our configuration window
- */
-
- struct NewWindow NewBlankerWindow =
- {
- 80, 16, 0, 0, 0, 1,
- IDCMP_CLOSEWINDOW | IDCMP_REFRESHWINDOW | IDCMP_GADGETDOWN |
- IDCMP_GADGETUP | IDCMP_VANILLAKEY | SLIDERIDCMP | LISTVIEWIDCMP,
- WINDOWCLOSE | WINDOWDRAG | WINDOWDEPTH | SIMPLE_REFRESH,
- NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0,
- WBENCHSCREEN
- };
-
- struct Window *BlankerWindow;
-
- #define GID_HIDE 1
- #define GID_BLANK 2
- #define GID_QUIT 3
- #define GID_TIMEOUT 4
- #define GID_CLIENT 5
- #define GID_EYES 6
- #define GID_SPEED 7
- #define GID_CHANCE 8
-
- #ifdef SMALLEYES
- #define NUM_GADS 7
- #else
- #define NUM_GADS 8
- #endif
-
- struct VisualInfo *BlankerVisualInfo;
- struct Gadgets *BlankerGadgets;
- struct TextAttr BlankerAttr =
- {"topaz.font", TOPAZ_EIGHTY, FS_NORMAL, FPF_ROMFONT};
-
- struct NewGadget NewBlankerGadgets[NUM_GADS] =
- {16, 101, 48, 12, "_Hide", &BlankerAttr, GID_HIDE, PLACETEXT_IN, NULL, NULL,
- 80, 101, 48, 12, "_Blank", &BlankerAttr, GID_BLANK, PLACETEXT_IN, NULL, NULL,
- 144, 101, 48, 12, "_Quit", &BlankerAttr, GID_QUIT, PLACETEXT_IN, NULL, NULL,
- 136, 5, 66, 12, "Timeout", &BlankerAttr, GID_TIMEOUT, PLACETEXT_LEFT, NULL, NULL,
- 136, 21, 66, 12, "Client Timeout", &BlankerAttr, GID_CLIENT, PLACETEXT_LEFT, NULL, NULL,
- 136, 53, 66, 12, "Speed ", &BlankerAttr, GID_SPEED, PLACETEXT_LEFT, NULL, NULL,
- 136, 69, 66, 12, "Eyes ", &BlankerAttr, GID_EYES, PLACETEXT_LEFT, NULL, NULL,
- #ifndef SMALLEYES
- 136, 37, 66, 12, "%Anim ", &BlankerAttr, GID_CHANCE, PLACETEXT_LEFT, NULL, NULL,
- #endif
- };
-
- UBYTE BlankerGadgetKinds[NUM_GADS] =
- {
- BUTTON_KIND, BUTTON_KIND, BUTTON_KIND, INTEGER_KIND, INTEGER_KIND, SLIDER_KIND,
- SLIDER_KIND,
- #ifndef SMALLEYES
- SLIDER_KIND
- #endif
- };
-
- struct TagItem ButtonGadgetTags[] =
- {GT_Underscore, (ULONG) '_', TAG_DONE, 0L};
-
- struct TagItem TimeGadgetTags[] =
- {GTIN_Number, 0L, GTIN_MaxChars, 4L, TAG_DONE, 0L};
-
- struct TagItem ClientGadgetTags[] =
- {GTIN_Number, 0L, GTIN_MaxChars, 2L, TAG_DONE, 0L};
-
- struct TagItem ChanceGadgetTags[] =
- {GTSL_Level, 0L, GTSL_Min, 1L, GTSL_Max, MAX_CHANCE, GTSL_LevelFormat, 0L,
- GTSL_LevelPlace, PLACETEXT_LEFT, GTSL_MaxLevelLen, 3L, GA_RELVERIFY, TRUE,
- TAG_DONE, 0L};
-
- struct TagItem SpeedGadgetTags[] =
- {GTSL_Level, 0L, GTSL_Min, 1L, GTSL_Max, MAX_SPEED, GTSL_LevelFormat, 0L,
- GTSL_LevelPlace, PLACETEXT_LEFT, GTSL_MaxLevelLen, 2L, GA_RELVERIFY, TRUE,
- TAG_DONE, 0L};
-
- struct TagItem EyesGadgetTags[] =
- {GTSL_Level, 0L, GTSL_Min, 1L, GTSL_Max, MAX_EYES, GTSL_LevelFormat, 0L,
- GTSL_LevelPlace, PLACETEXT_LEFT, GTSL_MaxLevelLen, 2L, GA_RELVERIFY, TRUE,
- TAG_DONE, 0L};
-
- struct TagItem *BlankerGadgetTagLists[NUM_GADS] =
- {
- &ButtonGadgetTags[0],
- &ButtonGadgetTags[0],
- &ButtonGadgetTags[0],
- &TimeGadgetTags[0],
- &ClientGadgetTags[0],
- &SpeedGadgetTags[0],
- &EyesGadgetTags[0],
- #ifndef SMALLEYES
- &ChanceGadgetTags[0],
- #endif
- };
-
- /*
- * Definitions for Server/Client Communication
- */
-
- BYTE bsp_TimerSig, bsp_InputSig, bsp_ClientSig;
- struct Task *BlankerServerProcess;
-
- #define MASK(n) (1L<<(n))
-
- struct ClientMessage {
- struct Message bcm_Message;
- struct RetinaScreen *bcm_Screen;
- LONG bcm_Status;
- ULONG bcm_SigMask;
- LONG bcm_Eyes, bcm_Speed, bcm_Chance;
- };
-
- /*
- * The following functions are used to track resources.
- */
- struct ToolNode {
- struct ToolNode *Next;
- void *Tool;
- void (*RemProc) (void *, LONG);
- LONG Size;
- }
-
- *ToolList;
-
- void __regargs
- RemTool(void *Tool)
- {
- struct ToolNode **Ptr, *ToolNode;
-
- Ptr = &ToolList;
- while (*Ptr)
- if ((*Ptr)->Tool == Tool) {
- ToolNode = *Ptr;
- *Ptr = (*Ptr)->Next;
- ToolNode->RemProc(ToolNode->Tool, ToolNode->Size);
- FreeMem(ToolNode, sizeof(struct ToolNode));
- } else
- Ptr = &(*Ptr)->Next;
- }
-
- void __regargs
- Quit(int ReturnCode, char *s)
- {
- while (ToolList)
- RemTool(ToolList->Tool);
- if (ReturnCode) Error(s);
- exit(ReturnCode);
- }
-
- void __regargs
- AddTool(void *NewTool, void *ProcPtr, LONG NewSize, char *errmsg)
- {
- struct ToolNode *Ptr;
- void (*NewRemProc) (void *, LONG);
-
- NewRemProc = ProcPtr;
- if (NewTool == NULL)
- Quit(10,errmsg);
-
- if ((Ptr = AllocMem(sizeof(struct ToolNode), MEMF_CLEAR)) == NULL) {
- NewRemProc(NewTool, NewSize);
- Quit(20,"Out of Memory.");
- }
- Ptr->Next = ToolList;
- Ptr->Tool = NewTool;
- Ptr->RemProc = NewRemProc;
- Ptr->Size = NewSize;
- ToolList = Ptr;
- }
-
- /*
- * Some utility functions
- */
-
- void __stdargs
- DeleteMsgPortSafely(struct MsgPort *AnyPort)
- {
- struct Message *AnyMsg;
-
- while (AnyMsg = GetMsg(AnyPort))
- ReplyMsg(AnyMsg);
- DeleteMsgPort(AnyPort);
- }
-
- int __regargs
- ArgIntMax(char **ToolTypes, char *ID, int Default, int Max)
- {
- int Val;
-
- Val = ArgInt(ToolTypes, ID, Default);
- if ((Val < 1) || (Val > Max))
- return Default;
- else
- return Val;
- }
-
- /*
- * The "InputHandler". It signals the server process
- * when an input or timer event is received.
- */
-
- void __interrupt __saveds
- BlankerAction(CxMsg * CxMsg, CxObj * CO)
- {
- struct InputEvent *IE;
-
- IE = (struct InputEvent *)CxMsgData(CxMsg);
- if (IE->ie_Class == IECLASS_TIMER)
- Signal(BlankerServerProcess, 1L << bsp_TimerSig);
- else
- Signal(BlankerServerProcess, 1L << bsp_InputSig);
- }
-
- /*
- * Functions for Handling the Configuration Window
- */
-
- LONG
- GetNum(struct Gadget *Gadget, LONG * Data, LONG Max)
- {
- LONG NewData;
-
- NewData = ((struct StringInfo *)Gadget->SpecialInfo)->LongInt;
- if ((NewData < 1L) || (NewData > Max)) {
- GT_SetGadgetAttrs(Gadget, BlankerWindow, NULL, GTIN_Number, (ULONG) * Data,
- TAG_DONE);
- return FALSE;
- } else {
- *Data = NewData;
- return TRUE;
- }
- }
-
- void
- CloseBlankerWindow(void)
- {
- if (BlankerWindow) {
- /*
- * We save the current position of the window
- * so it will re-open in the same place, later.
- */
- NewBlankerWindow.LeftEdge = BlankerWindow->LeftEdge;
- NewBlankerWindow.TopEdge = BlankerWindow->TopEdge;
-
- RemTool(BlankerGadgets);
- RemTool(BlankerVisualInfo);
- RemTool(BlankerWindow);
- BlankerWindow = NULL;
- }
- }
-
- void
- OpenBlankerWindow(void)
- {
- struct Gadget *Ptr;
- UWORD Index;
- static char Title[80];
-
- if (BlankerWindow == NULL) {
- strcpy(Title, "REyes = <");
- strcat(Title, PopKey);
- strcat(Title, ">");
-
- if (BlankerWindow = OpenWindowTags(&NewBlankerWindow, WA_Title, Title,
- WA_AutoAdjust, TRUE, WA_InnerWidth,
- 212, WA_InnerHeight, 118, TAG_DONE)) {
-
- AddTool(BlankerWindow, CloseWindow, NULL,"Could not open the window.");
-
- if ((BlankerVisualInfo = GetVisualInfo(BlankerWindow->WScreen, TAG_DONE))
- == NULL) {
- RemTool(BlankerWindow);
- return;
- }
- AddTool(BlankerVisualInfo, FreeVisualInfo, 0L,
- "Couldn't get visual data.");
-
- BlankerGadgets = NULL;
- if ((Ptr = CreateContext(&BlankerGadgets)) == NULL) {
- RemTool(BlankerVisualInfo);
- RemTool(BlankerWindow);
- return;
- }
- AddTool(Ptr, FreeGadgets, 0L,"Couldn't allocate the gadgets.");
-
- /* Here we re-load the gadgets with the current settings. */
- TimeGadgetTags[0].ti_Data = (ULONG) TimeOut;
- ClientGadgetTags[0].ti_Data = (ULONG) ClientTimeOut;
- SpeedGadgetTags[0].ti_Data = (ULONG) Speed;
- SpeedGadgetTags[3].ti_Data = (ULONG) "%2ld";
- #ifndef SMALLEYES
- ChanceGadgetTags[0].ti_Data = (ULONG) Chance;
- ChanceGadgetTags[3].ti_Data = (ULONG) "%3ld";
- #endif
- EyesGadgetTags[0].ti_Data = (ULONG) NumEyes;
- EyesGadgetTags[3].ti_Data = (ULONG) "%2ld";
-
- for (Index = 0L; Index < NUM_GADS; Index++) {
- NewBlankerGadgets[Index].ng_TopEdge += BlankerWindow->BorderTop;
-
- NewBlankerGadgets[Index].ng_VisualInfo = BlankerVisualInfo;
- Ptr = CreateGadgetA((ULONG) BlankerGadgetKinds[Index], Ptr,
- &NewBlankerGadgets[Index],
- BlankerGadgetTagLists[Index]);
- if (Ptr == NULL) {
- CloseBlankerWindow();
- return;
- }
- NewBlankerGadgets[Index].ng_TopEdge -= BlankerWindow->BorderTop;
- }
-
- AddGList(BlankerWindow, BlankerGadgets, 0L, -1L, NULL);
- RefreshGadgets(BlankerGadgets, BlankerWindow, NULL);
- GT_RefreshWindow(BlankerWindow, NULL);
- }
- }
- ScreenToFront(BlankerWindow->WScreen);
- WindowToFront(BlankerWindow);
- ActivateWindow(BlankerWindow);
- }
-
- /*
- * Function to handle the Commodity Stuff
- */
-
- void __regargs
- HandleCxMsg(CxObj * Broker, CxMsg * CxMsg, LONG * TimeUntilBlank,
- LONG * ThisTimeOut)
- {
- ULONG MsgType, MsgID;
-
- MsgType = CxMsgType(CxMsg);
- MsgID = CxMsgID(CxMsg);
- ReplyMsg((struct Message *)CxMsg);
-
- switch (MsgType) {
- case CXM_IEVENT: /* a hotkey was pressed */
- switch (MsgID) {
- case HOTKEY_OPEN_WINDOW:
- OpenBlankerWindow();
- break;
- case HOTKEY_BLANK_SCREEN:
- if (*TimeUntilBlank)
- *TimeUntilBlank = *ThisTimeOut = 2L;
- }
- case CXM_COMMAND:
- switch (MsgID) {
- case CXCMD_DISABLE: /* Message from Exchange
- * (except CXCMD_UNIQUE) */
- (void)ActivateCxObj(Broker, FALSE);
- break;
- case CXCMD_ENABLE:
- (void)ActivateCxObj(Broker, TRUE);
- break;
- case CXCMD_UNIQUE:
- case CXCMD_APPEAR:
- OpenBlankerWindow();
- break;
- case CXCMD_DISAPPEAR:
- CloseBlankerWindow();
- break;
- case CXCMD_KILL:
- Quit(0,"Normal Termination.");
- }
- }
- }
-
- #ifdef OBSOLETE
- /*
- * These functions have been replaced by defines.
- * They're provided here for hysterical raisins.
- */
- void
- SpritesOff(struct RetinaScreen *rs)
- {
- struct TagItem tags[] =
- {RSP_On, 0L, TAG_DONE, 0L};
-
- Retina_SpriteFunction(rs, tags);
- }
-
- void
- SpritesOn(struct RetinaScreen *rs)
- {
- struct TagItem tags[] =
- {RSP_On, 1L, TAG_DONE, 0L};
-
- Retina_SpriteFunction(rs, tags);
- }
- #else
- /*
- * We use defines for these functions just to pick up a little speed.
- */
-
- #define SpritesOff(rs) \
- { \
- struct TagItem tags[] = \
- {RSP_On, 0L, TAG_DONE, 0L}; \
- \
- Retina_SpriteFunction(rs, tags);\
- }
-
- #define SpritesOn(rs) \
- { \
- struct TagItem tags[] = \
- {RSP_On, 1L, TAG_DONE, 0L}; \
- \
- Retina_SpriteFunction(rs, tags);\
- }
- #endif
-
- /*
- * This, annoyingly enough, is neccessary because Retina_CloseScreen is
- * actually a #pragma and not a real function call. This means you
- * can't pass a pointer to Retina_CloseScreen as a function argument
- * to AddTool. By adding this wrapper function, we make AddTool work.
- */
- void
- DestroyScreen(struct RetinaScreen *rs)
- {
- Retina_CloseScreen(rs);
- }
-
- /*
- * Create Screen will first attempt to open a "normal" resolution screen.
- * If that fails, it will try opening a lower resolution screen.
- * If that fails it will return NULL.
- */
- struct RetinaScreen *
- CreateScreen(void)
- {
- struct RetinaScreen *Screen;
-
- if (!(Screen = Retina_OpenScreen(NORMAL_WIDE, NORMAL_HIGH, MID_DEFAULT_08,
- RSFF_DOUBLEBUFFER, NULL)))
- if (!(Screen = Retina_OpenScreen(SMALL_WIDE, SMALL_HIGH, MID_DEFAULT_08,
- RSFF_DOUBLEBUFFER, NULL)))
- return NULL;
-
- Retina_LoadPalette(Screen, 0, EYES_COLS, color_table);
- SpritesOff(Screen);
- return Screen;
- }
-
- /*
- * Functions for Creating/Deleting the Client Process
- */
-
- void __stdargs
- DeleteBlankerClient(struct MsgPort * ClientPort)
- {
- struct ClientMessage ClientMessage;
-
- /* Send the terminating message to the client.
- * We kick up the client's priority to ensure a
- * prompt response.
- */
- Forbid();
- ClientMessage.bcm_Message.mn_ReplyPort = FINDPROCPORT;
- PutMsg(ClientPort, (struct Message *)&ClientMessage);
-
- (void)SetTaskPri(ClientPort->mp_SigTask, SERVER_PRI);
- Permit();
-
- /* Get the response. */
- (void)WaitPort(ClientMessage.bcm_Message.mn_ReplyPort);
- (void)GetMsg(ClientMessage.bcm_Message.mn_ReplyPort);
- }
-
- struct MsgPort *__regargs
- CreateBlankerClient(void *ClientRoutine, struct ClientMessage *ClientMessage)
- {
- struct Process *ClientProcess;
- struct TagItem ProcTags[3];
-
- ProcTags[0].ti_Tag = NP_Entry;
- ProcTags[0].ti_Data = (ULONG) ClientRoutine;
- ProcTags[1].ti_Tag = NP_Name;
- ProcTags[1].ti_Data = (ULONG) "ClientProcess";
- ProcTags[2].ti_Tag = TAG_DONE;
-
- if (ClientProcess = CreateNewProc(ProcTags)) {
- ClientMessage->bcm_Message.mn_ReplyPort = FINDPROCPORT;
- PutMsg(&ClientProcess->pr_MsgPort, (struct Message *)ClientMessage);
-
- (void)WaitPort(ClientMessage->bcm_Message.mn_ReplyPort);
- (void)GetMsg(ClientMessage->bcm_Message.mn_ReplyPort);
-
- (void)SetTaskPri((struct Task *)ClientProcess, CLIENT_PRI);
-
- if (ClientMessage->bcm_Status)
- return &ClientProcess->pr_MsgPort;
- }
- return NULL;
- }
-
- /*
- * Functions for Creating/Drawing/Removing the Eyes
- */
-
- LONG __inline
- Insure1(LONG val)
- {
- return ((val == 0) ? 1 : val); /* return value that is at least 1 */
- }
-
- /*
- * This is a fairly high-speed psuedo random number generator,
- * but it's not to random, though. Occasionally, it will
- * be non-random enough for a while to cause all the Eyes to
- * move in the same direction (or some such.) I use it
- * because it's fast and because, with all the collision
- * detection done now, it's less likely the un-randomness
- * will be noticed.
- */
- WORD __regargs
- Random(WORD Max)
- {
- static ULONG Num = 0L;
- ULONG Sec, Mic;
-
- CurrentTime((LONG *) & Sec, (LONG *) & Mic);
-
- Num *= Sec;
- Num += Mic;
-
- while (Num > 32767L)
- Num = Num >> 1;
-
- return (WORD) Num % Max;
- }
-
- /*
- * Free up the list of eyes.
- */
- void __regargs
- DeleteEyes(EyeStruct *EyeList)
- {
- LONG i;
-
- for (i=0;i<EyeList->NumEyes;i++)
- if (EyeList->Eye[i]!=NULL) FreeMem(EyeList->Eye[i],sizeof(Eyes));
- }
-
- /*
- * Create the list of eyes.
- */
- EyeStruct *__regargs
- CreateEyes(struct RetinaScreen *Screen,
- LONG NumEyes, LONG Speed)
- {
- int Index, i, flag, count;
- Eyes *randomeyes[4];
-
- if (!Screen) return NULL;
-
- randomeyes[0]=&BlueEyes;
- randomeyes[1]=&GreenEyes;
- randomeyes[2]=&VioletEyes;
- randomeyes[3]=&BrownEyes;
-
- /*
- * Create the Eyes
- */
- for (Index = 0; Index < NumEyes; Index++) {
- if (!(EyeList.Eye[Index]=AllocMem(sizeof(Eyes),MEMF_PUBLIC|MEMF_CLEAR)))
- Quit(20,"Out of Memory!!!");
- CopyMem(randomeyes[Random(4)],EyeList.Eye[Index],sizeof(Eyes));
- #ifndef SMALLEYES
- EyeList.Eye[Index]->currentframe=Random(EyeList.Eye[Index]->maxframes);
- #else
- EyeList.Eye[Index]->currentframe=0;
- #endif
- EyeList.Eye[Index]->xspeed=Insure1(RAND(Speed));
- EyeList.Eye[Index]->yspeed=Insure1(RAND(Speed));
- count=0; flag=1;
-
- /*
- * We try 4 times to fit an eye pair on the screen. If we can't, then
- * the screen must be too small for the # of eyes and we truncate the list.
- */
- while (flag & count<4) {
- EyeList.Eye[Index]->xpos=Random(Screen->rs_Width-
- EyeList.Eye[Index]->width);
- EyeList.Eye[Index]->ypos=Random(Screen->rs_Height-
- EyeList.Eye[Index]->height);
- flag=0;
- for (i=0;i<Index; i++) {
- /* Looking for overlapping rectangles... */
- if ((EyeList.Eye[i]->xpos>
- EyeList.Eye[Index]->xpos-EyeList.Eye[i]->width)&&
- (EyeList.Eye[i]->xpos<
- EyeList.Eye[Index]->xpos+EyeList.Eye[Index]->width)&&
- (EyeList.Eye[i]->ypos>
- EyeList.Eye[Index]->ypos-EyeList.Eye[i]->height)&&
- (EyeList.Eye[i]->ypos<
- EyeList.Eye[Index]->ypos+EyeList.Eye[Index]->height)) {
- flag=1;
- break;
- }
- }
- }
- if (flag) { /* If we failed to add an Eye pair, truncate the list. */
- NumEyes=Index+1;
- break;
- }
- }
-
- EyeList.NumEyes=NumEyes;
-
- return &EyeList;
- }
-
- /* move the Eyes and redraw them */
-
- void __regargs
- DrawEyes(EyeStruct *EyeList, struct RetinaScreen *rs, LONG Chance)
- {
- int Index,i;
- Eyes **EL;
-
- /*
- * This assignment provides a (very mild) speed up buy removing
- * one level of indirection from all the work that's going on below.
- */
- EL=EyeList->Eye;
-
- Chance=Insure1(100-Chance);
-
- /* If we don't have a screen, don't draw on it! (duh.) */
- if (!rs) return;
-
- for (Index=0; Index<EyeList->NumEyes; Index++) {
- /* Move the Eye. */
- EL[Index]->old_xpos=EL[Index]->xpos;
- EL[Index]->old_ypos=EL[Index]->ypos;
- EL[Index]->xpos+=EL[Index]->xspeed;
- EL[Index]->ypos+=EL[Index]->yspeed;
-
- /* Bounce check */
- if (EL[Index]->xpos<0) {
- EL[Index]->xpos=0;
- EL[Index]->xspeed=Insure1(RAND(Speed));
- } else if (EL[Index]->xpos>rs->rs_Width-EL[Index]->width-1) {
- EL[Index]->xpos=rs->rs_Width-EL[Index]->width-1;
- EL[Index]->xspeed=Insure1(RAND(Speed));
- }
- if (EL[Index]->ypos<0) {
- EL[Index]->ypos=0;
- EL[Index]->yspeed=Insure1(RAND(Speed));
- } else if (EL[Index]->ypos>rs->rs_Height-EL[Index]->height-1) {
- EL[Index]->ypos=rs->rs_Height-EL[Index]->height-1;
- EL[Index]->yspeed=Insure1(RAND(Speed));
- }
-
- /*
- * Collision check...
- * If we detect that we hit one other eye pair, we reverse direction.
- * Note - checking stops after the first collision, otherwise
- * multiple-collisions might cause the eye pair to continue in
- * the same direction (i.e., its direction got negated twice)
- */
- for (i=0;i<EyeList->NumEyes; i++) {
- if (i!=Index) {
- if ((EL[i]->xpos>EL[Index]->xpos-EL[i]->width)&&
- (EL[i]->xpos<EL[Index]->xpos+EL[Index]->width)&&
- (EL[i]->ypos>EL[Index]->ypos-EL[i]->height)&&
- (EL[i]->ypos<EL[Index]->ypos+EL[Index]->height)) {
-
- EL[Index]->yspeed= (EL[Index]->yspeed>0)?-Insure1(Random(Speed/2)):Insure1(Random(Speed/2));
- EL[Index]->xspeed= (EL[Index]->xspeed>0)?-Insure1(Random(Speed/2)):Insure1(Random(Speed/2));
- EL[Index]->xpos=EL[Index]->old_xpos;
- EL[Index]->ypos=EL[Index]->old_ypos;
- break;
- }
- }
- }
- #ifndef SMALLEYES
- /* Are we animating this Eye pair? */
- if (EL[Index]->currentframe) {
- if (!EL[Index]->tic) {
- EL[Index]->tic++;
- } else {
- EL[Index]->tic=0;
- EL[Index]->currentframe=(EL[Index]->currentframe+1)%
- EL[Index]->maxframes;
- }
- /* No? Then roll the dice and see if we should start... */
- } else if (!Random(Chance)) {
- EL[Index]->currentframe=1;
- }
- #endif
-
- }
-
- /* Redraw on the background bitmap... */
- for (Index=0; Index<EyeList->NumEyes; Index++) {
- Retina_WriteRect(EL[Index]->animtable[EL[Index]->currentframe],
- 0,0,
- EL[Index]->width, RECTMODE_256,
- rs,EL[Index]->xpos, EL[Index]->ypos,
- EL[Index]->width, EL[Index]->height, NULL);
-
- }
-
- /* Swap the bitmaps */
- Retina_SwapBitMap(rs);
-
- /* Erase the old images on the new background bitmap. */
- for (Index=0; Index<EyeList->NumEyes; Index++) {
- Retina_RectFill(rs,EL[Index]->old_xpos,
- EL[Index]->old_ypos,
- EL[Index]->old_xpos+EL[Index]->width,
- EL[Index]->old_ypos+EL[Index]->height);
- }
- }
-
- /*
- * This is the Client Process's Main Loop
- */
-
- void __interrupt __saveds
- REyesClientProcess(void)
- {
- struct ClientMessage *ClientMessage;
- struct MsgPort *ClientPort;
- struct Task *BlankerServerTask;
- ULONG BlankerServerSigMask;
- struct RetinaScreen *EyesScreen;
- LONG NumEyes, Speed, Chance;
- EyeStruct *EyeList;
-
- /* wait for Server's initial Message */
-
- ClientPort = FINDPROCPORT;
- (void)WaitPort(ClientPort);
- ClientMessage = (struct ClientMessage *)GetMsg(ClientPort);
-
- BlankerServerTask = ClientMessage->bcm_Message.mn_ReplyPort->mp_SigTask;
- BlankerServerSigMask = ClientMessage->bcm_SigMask;
-
- NumEyes = ClientMessage->bcm_Eyes;
- Speed = ClientMessage->bcm_Speed;
- Chance = ClientMessage->bcm_Chance;
- EyesScreen = ClientMessage->bcm_Screen;
-
- if (EyesScreen) {
- if ((EyeList = CreateEyes(EyesScreen, NumEyes, Speed))== NULL) {
- ClientMessage->bcm_Status = FALSE;
- Forbid();
- ReplyMsg((struct Message *)ClientMessage);
- return;
- }
- }
-
- ClientMessage->bcm_Status = TRUE;
- ReplyMsg((struct Message *)ClientMessage);
-
- /* Animate the blanker screen until a termination message is received. */
- while ((ClientMessage = (struct ClientMessage *)GetMsg(ClientPort)) == NULL) {
- if (EyesScreen) DrawEyes(EyeList, EyesScreen, Chance);
-
- /*
- * We signal the server after each loop so it will know that we're alive.
- */
- Signal(BlankerServerTask, BlankerServerSigMask);
- }
-
- /* We are requested to finish, so we do. */
-
- if (EyeList) DeleteEyes(EyeList);
- Forbid();
- ReplyMsg((struct Message *)ClientMessage);
- }
-
- /*
- * The Main Loop
- */
-
- void
- main(LONG argc, UBYTE * argv[])
- {
- char **ToolTypes;
- CxObj *Broker, *ObjectList, *Filter;
- struct IntuiMessage *IntMsg;
- CxMsg *BlankerCxMsg;
- LONG ThisTimeOut, TimeUntilBlank, TimeUntilBlack;
- struct RetinaScreen *BlankerScreen = NULL;
- struct ClientPort *ClientPort = NULL;
-
- /* open our Libraries */
- AddTool(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",
- 37L), CloseLibrary, 0L,
- "Couldn't open the intuition.library.");
- AddTool(IconBase = OpenLibrary("icon.library", 37L), CloseLibrary, 0L,
- "Couldn't open the icon library.");
- AddTool(CxBase = OpenLibrary("commodities.library", 37L), CloseLibrary, 0L,
- "Couldn't open the commoidities library.");
- AddTool(GadToolsBase = OpenLibrary("gadtools.library", 37L), CloseLibrary, 0L,
- "Couldn't open the gadtools library.");
- AddTool(RetinaBase = (struct _xy_RetinaBase *)OpenLibrary("retina.library", 7L),
- CloseLibrary, 0L,"Couldn't open the Retina library.");
-
- /* get our Arguments */
-
- if (ToolTypes = ArgArrayInit(argc, argv))
- AddTool(ToolTypes, ArgArrayDone, 0L,NULL);
-
- /* get some Signals */
-
- BlankerServerProcess = SysBase->ThisTask;
- if ((bsp_TimerSig = AllocSignal(-1L)) == -1)
- Quit(10,"Could not allocate a signal.");
- AddTool((void *)bsp_TimerSig, FreeSignal, 0L,NULL);
- if ((bsp_InputSig = AllocSignal(-1L)) == -1)
- Quit(10,"Could not allocate a signal.");
- AddTool((void *)bsp_InputSig, FreeSignal, 0L,NULL);
- if ((bsp_ClientSig = AllocSignal(-1L)) == -1)
- Quit(10,"Could not allocate a signal.");
- AddTool((void *)bsp_ClientSig, FreeSignal, 0L,NULL);
-
- /* initialize our Broker = install us as a Commodity */
-
- AddTool(CxPort = CreateMsgPort(), DeleteMsgPortSafely, 0L,
- "Failed to create a port.");
-
- NewBroker.nb_Pri = ArgInt(ToolTypes, "CX_PRIORITY", DEF_CX_PRI);
- NewBroker.nb_Port = CxPort;
- AddTool(Broker = CxBroker(&NewBroker, NULL), DeleteCxObjAll, 0L,
- NULL);
-
- /* get Time Out, Client Time Out and Display mode */
-
- TimeOut = ArgIntMax(ToolTypes, "TIMEOUT", DEF_TIMEOUT, MAX_TIMEOUT);
- ClientTimeOut = ArgIntMax(ToolTypes, "CLIENTTIMEOUT", DEF_CLIENT_TIMEOUT,
- MAX_CLIENT_TIMEOUT);
-
- /* get Parameters for Eye Movement */
-
- NumEyes = ArgIntMax(ToolTypes, "EYES", DEF_EYES, MAX_EYES);
- Speed = ArgIntMax(ToolTypes, "SPEED", DEF_SPEED, MAX_SPEED);
- Chance = ArgIntMax(ToolTypes, "%ANIM", DEF_CHANCE, MAX_CHANCE);
-
- /* install our hot keys */
-
- PopKey = ArgString(ToolTypes, "CX_POPKEY", DEF_POPKEY);
- BlankKey = ArgString(ToolTypes, "BLANKKEY", DEF_BLANKKEY);
-
- if ((Filter = HotKey(PopKey, CxPort, HOTKEY_OPEN_WINDOW)) == NULL)
- Quit(10,"The CX_POPKEY tool type is invalid.");
- else
- AttachCxObj(Broker, Filter);
- if (CxObjError(Filter))
- Quit(10,"Could not link to the commodity list.");
-
- if ((Filter = HotKey(BlankKey, CxPort, HOTKEY_BLANK_SCREEN)) == NULL)
- Quit(10,"The BLANKKEY tool type is invalid.");
- else
- AttachCxObj(Broker, Filter);
- if (CxObjError(Filter))
- Quit(10,"Could not link to the commodity list.");
-
- /* install our "InputHandler" */
-
- ObjectList = CxCustom(BlankerAction, 0L);
- AttachCxObj(Broker, ObjectList);
- if (CxObjError(ObjectList))
- Quit(10,"Could not link to the commodity list.");
-
- (void)ActivateCxObj(Broker, TRUE);
- AddTool(Broker, ActivateCxObj, 0L,"The broker broke.");
-
- /* open Window on startup if not forbidden */
-
- if (stricmp(ArgString(ToolTypes, "CX_POPUP", ""), "NO"))
- OpenBlankerWindow();
-
- /* increase our Priority */
-
- AddTool(FindTask(NULL), SetTaskPri, (LONG) SetTaskPri(FindTask(NULL), SERVER_PRI),
- "Findtask failed!");
-
- /* start the Loop */
-
- TimeUntilBlank = ThisTimeOut = 10L * TimeOut;
- TimeUntilBlack = 10L * ClientTimeOut;
-
- FOREVER
- {
- ULONG Mask;
-
- if (BlankerWindow)
- Mask = Wait(MASK(bsp_TimerSig) | MASK(bsp_InputSig) | MASK(bsp_ClientSig) |
- MASK(CxPort->mp_SigBit) |
- MASK(BlankerWindow->UserPort->mp_SigBit) |
- SIGBREAKF_CTRL_C);
- else
- Mask = Wait(MASK(bsp_TimerSig) | MASK(bsp_InputSig) | MASK(bsp_ClientSig) |
- MASK(CxPort->mp_SigBit) | SIGBREAKF_CTRL_C);
-
- /* process Window Events */
-
- while ((BlankerWindow != NULL) && (IntMsg =
- GT_GetIMsg(BlankerWindow->UserPort)))
- switch (IntMsg->Class) {
- struct Gadget *Clicked;
- UWORD Code;
-
- case IDCMP_CLOSEWINDOW:
- GT_ReplyIMsg(IntMsg);
- CloseBlankerWindow();
- break;
- case IDCMP_REFRESHWINDOW:
- GT_BeginRefresh(BlankerWindow);
- GT_EndRefresh(BlankerWindow, TRUE);
- break;
- case IDCMP_GADGETUP:
- Code = IntMsg->Code;
- Clicked = (struct Gadget *)IntMsg->IAddress;
- GT_ReplyIMsg(IntMsg);
- switch (Clicked->GadgetID) {
- case GID_HIDE:
- CloseBlankerWindow();
- break;
- case GID_QUIT:
- Quit(0,"Normal Termination.");
- case GID_BLANK:
- if (TimeUntilBlank)
- TimeUntilBlank = ThisTimeOut = 2L;
- break;
- case GID_TIMEOUT:
- if (GetNum(Clicked, &TimeOut, MAX_TIMEOUT))
- TimeUntilBlank = ThisTimeOut = 10L * TimeOut;
- break;
- case GID_CLIENT:
- if (GetNum(Clicked, &ClientTimeOut, MAX_CLIENT_TIMEOUT))
- TimeUntilBlack = 10L * ClientTimeOut;
- break;
- case GID_EYES:
- NumEyes = Code;
- break;
- case GID_SPEED:
- Speed = Code;
- break;
- case GID_CHANCE:
- Chance = Code;
- break;
- }
- break;
- case IDCMP_VANILLAKEY:
- Code = IntMsg->Code;
- GT_ReplyIMsg(IntMsg);
- switch ((char)Code) {
- case 'H':
- case 'h':
- CloseBlankerWindow();
- break;
- case 'Q':
- case 'q':
- Quit(0,"Normal Termination.");
- case 'B':
- case 'b':
- if (TimeUntilBlank)
- TimeUntilBlank = ThisTimeOut = 2L;
- }
- break;
- default:
- GT_ReplyIMsg(IntMsg);
- }
-
- /* process Commodity Messages */
-
- while (BlankerCxMsg = (CxMsg *) GetMsg(CxPort))
- HandleCxMsg(Broker, BlankerCxMsg, &TimeUntilBlank, &ThisTimeOut);
-
- /* check for <CTRL>-C */
-
- if (Mask & SIGBREAKF_CTRL_C)
- Quit(0,"Normal Termination.");
-
- /* Input detected, unblank if necessary */
-
- if (Mask & MASK(bsp_InputSig)) {
- if (TimeUntilBlank == 0L) {
- if (ClientPort)
- RemTool(ClientPort);
-
- if (BlankerScreen) {
- SpritesOn(BlankerScreen);
- RemTool(BlankerScreen);
- } else
- Retina_DisplayOn();
-
- ThisTimeOut = 10L * TimeOut;
- }
- TimeUntilBlank = ThisTimeOut;
- }
-
- /* client has confirmed that it is still alive */
- if (Mask & MASK(bsp_ClientSig)) {
- if (BlankerScreen) Retina_DisplayOn();
- TimeUntilBlack = 10L * ClientTimeOut;
- }
- /* 1/10 sec is over */
-
- if (Mask & MASK(bsp_TimerSig))
- if (TimeUntilBlank) {
- TimeUntilBlank--;
- if (TimeUntilBlank == 0L) { /* Time Out reached, blank
- * the screen */
- struct ClientMessage ClientMessage;
-
- BlankerScreen=CreateScreen();
- if (BlankerScreen)
- AddTool(BlankerScreen, DestroyScreen, 0L,NULL);
- else
- /* do this if we're completely out of video memory. */
- Retina_DisplayOff();
-
- ClientMessage.bcm_Screen = BlankerScreen;
- ClientMessage.bcm_SigMask = 1L << bsp_ClientSig;
- ClientMessage.bcm_Eyes = NumEyes;
- ClientMessage.bcm_Speed = Speed;
- ClientMessage.bcm_Chance = Chance;
-
- if (ClientPort = CreateBlankerClient(REyesClientProcess,
- &ClientMessage)) {
- TimeUntilBlack = 10L * ClientTimeOut;
- /* try to start Client */
- AddTool(ClientPort, DeleteBlankerClient, 0L,NULL);
- }
- }
- } else {
- if ((BlankerScreen)&&(RetinaBase->rb_FirstScreen != BlankerScreen)) {
- Retina_ScreenToFront(BlankerScreen);
- SpritesOff(BlankerScreen);
- }
- if (TimeUntilBlack) {
- TimeUntilBlack--;
- if (TimeUntilBlack == 0L)
- Retina_DisplayOff(); /* Client Time Out
- * reached, turn entire
- * screen black */
- }
- }
- }
- }
-